<!DOCTYPE html>
<html lang="en" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>G4F - File API Documentation with Web Download and Enhanced File Support</title>
    <link rel="apple-touch-icon" sizes="180x180" href="/dist/img/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="/dist/img/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="/dist/img/favicon-16x16.png">
    <link rel="manifest" href="/dist/img/site.webmanifest">
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-74231a1f3bbb.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-8a995f0bacd4.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-225433424a87.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-b8b91660c29d.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-205098e9fedd.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-177d21388df8.css" />
    <style>
        :root {
            --colour-1: #000000;
            --colour-2: #ccc;
            --colour-3: #e4d4ff;
            --colour-4: #f0f0f0;
            --colour-5: #181818;
            --colour-6: #242424;
            --accent: #8b3dff;
            --gradient: #1a1a1a;
            --background: #16101b;
            --size: 70vw;
            --top: 50%;
            --blur: 40px;
            --opacity: 0.6;
        }

        /* Body and text color */
        body {
            height: 100vh;
            margin: 0;
            padding: 0;
        }

        .hidden {
            display: none;
        }

        .container-lg {
            margin: 0 auto;
            padding: 8px;
        }

        @media only screen and (min-width: 40em) {
            .container-lg {
                max-width: 84%;
            }
        }
    </style>
</head>
<body>
    <article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading"><h2 class="heading-element">G4F - File API Documentation with Web Download and Enhanced File Support</h2><a id="user-content-g4f---file-api-documentation-with-web-download-and-enhanced-file-support" class="anchor" aria-label="Permalink: G4F - File API Documentation with Web Download and Enhanced File Support" href="#g4f---file-api-documentation-with-web-download-and-enhanced-file-support"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
<p>This document details the enhanced G4F File API, allowing users to upload files, download files from web URLs, and process a wider range of file types for integration with language models.</p>
<p><strong>Key Improvements:</strong></p>
<ul>
<li>
<p><strong>Web URL Downloads:</strong>  Upload a <code>downloads.json</code> file to your bucket containing a list of URLs. The API will download and process these files.  Example: <code>[{"url": "https://example.com/document.pdf"}]</code></p>
</li>
<li>
<p><strong>Expanded File Support:</strong>  Added support for additional plain text file extensions:  <code>.txt</code>, <code>.xml</code>, <code>.json</code>, <code>.js</code>, <code>.har</code>, <code>.sh</code>, <code>.py</code>, <code>.php</code>, <code>.css</code>, <code>.yaml</code>, <code>.sql</code>, <code>.log</code>, <code>.csv</code>, <code>.twig</code>, <code>.md</code>.  Binary file support remains for <code>.pdf</code>, <code>.html</code>, <code>.docx</code>, <code>.odt</code>, <code>.epub</code>, <code>.xlsx</code>, and <code>.zip</code>.</p>
</li>
<li>
<p><strong>Server-Sent Events (SSE):</strong>  SSE are now used to provide asynchronous updates on file download and processing progress. This improves the user experience, particularly for large files and multiple downloads.</p>
</li>
</ul>
<p><strong>API Endpoints:</strong></p>
<ul>
<li>
<p><strong>Upload:</strong> <code>/v1/files/{bucket_id}</code> (POST)</p>
<ul>
<li>
<strong>Method:</strong> POST</li>
<li>
<strong>Path Parameters:</strong> <code>bucket_id</code> (Generated by your own. For example a UUID)</li>
<li>
<strong>Body:</strong> Multipart/form-data with files OR a <code>downloads.json</code> file containing URLs.</li>
<li>
<strong>Response:</strong> JSON object with <code>bucket_id</code>, <code>url</code>, and a list of uploaded/downloaded filenames.</li>
</ul>
</li>
<li>
<p><strong>Retrieve:</strong> <code>/v1/files/{bucket_id}</code> (GET)</p>
<ul>
<li>
<strong>Method:</strong> GET</li>
<li>
<strong>Path Parameters:</strong> <code>bucket_id</code>
</li>
<li>
<strong>Query Parameters:</strong>
<ul>
<li>
<code>delete_files</code>: (Optional, boolean, default <code>true</code>) Delete files after retrieval.</li>
<li>
<code>refine_chunks_with_spacy</code>: (Optional, boolean, default <code>false</code>) Apply spaCy-based refinement.</li>
</ul>
</li>
<li>
<strong>Response:</strong> Streaming response with extracted text, separated by ``` markers.  SSE updates are sent if the <code>Accept</code> header includes `text/event-stream`.</li>
</ul>
</li>
</ul>
<p><strong>Example Usage (Python):</strong></p>
<div class="highlight highlight-source-python"><pre><span class="pl-k">import</span> <span class="pl-s1">requests</span>
<span class="pl-k">import</span> <span class="pl-s1">uuid</span>
<span class="pl-k">import</span> <span class="pl-s1">json</span>

<span class="pl-k">def</span> <span class="pl-en">upload_and_process</span>(<span class="pl-s1">files_or_urls</span>, <span class="pl-s1">bucket_id</span><span class="pl-c1">=</span><span class="pl-c1">None</span>):
    <span class="pl-k">if</span> <span class="pl-s1">bucket_id</span> <span class="pl-c1">is</span> <span class="pl-c1">None</span>:
        <span class="pl-s1">bucket_id</span> <span class="pl-c1">=</span> <span class="pl-en">str</span>(<span class="pl-s1">uuid</span>.<span class="pl-c1">uuid4</span>())
    
    <span class="pl-k">if</span> <span class="pl-en">isinstance</span>(<span class="pl-s1">files_or_urls</span>, <span class="pl-s1">list</span>): <span class="pl-c">#URLs</span>
        <span class="pl-s1">files</span> <span class="pl-c1">=</span> {<span class="pl-s">'files'</span>: (<span class="pl-s">'downloads.json'</span>, <span class="pl-s1">json</span>.<span class="pl-c1">dumps</span>(<span class="pl-s1">files_or_urls</span>), <span class="pl-s">'application/json'</span>)}
    <span class="pl-k">elif</span> <span class="pl-en">isinstance</span>(<span class="pl-s1">files_or_urls</span>, <span class="pl-s1">dict</span>): <span class="pl-c">#Files</span>
        <span class="pl-s1">files</span> <span class="pl-c1">=</span> <span class="pl-s1">files_or_urls</span>
    <span class="pl-k">else</span>:
        <span class="pl-k">raise</span> <span class="pl-en">ValueError</span>(<span class="pl-s">"files_or_urls must be a list of URLs or a dictionary of files"</span>)

    <span class="pl-s1">upload_response</span> <span class="pl-c1">=</span> <span class="pl-s1">requests</span>.<span class="pl-c1">post</span>(<span class="pl-s">f'http://localhost:1337/v1/files/<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">bucket_id</span><span class="pl-kos">}</span></span>'</span>, <span class="pl-s1">files</span><span class="pl-c1">=</span><span class="pl-s1">files</span>)

    <span class="pl-k">if</span> <span class="pl-s1">upload_response</span>.<span class="pl-c1">status_code</span> <span class="pl-c1">==</span> <span class="pl-c1">200</span>:
        <span class="pl-s1">upload_data</span> <span class="pl-c1">=</span> <span class="pl-s1">upload_response</span>.<span class="pl-c1">json</span>()
        <span class="pl-en">print</span>(<span class="pl-s">f"Upload successful. Bucket ID: <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">upload_data</span>[<span class="pl-s">'bucket_id'</span>]<span class="pl-kos">}</span></span>"</span>)
    <span class="pl-k">else</span>:
        <span class="pl-en">print</span>(<span class="pl-s">f"Upload failed: <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">upload_response</span>.<span class="pl-c1">status_code</span><span class="pl-kos">}</span></span> - <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">upload_response</span>.<span class="pl-c1">text</span><span class="pl-kos">}</span></span>"</span>)

    <span class="pl-s1">response</span> <span class="pl-c1">=</span> <span class="pl-s1">requests</span>.<span class="pl-c1">get</span>(<span class="pl-s">f'http://localhost:1337/v1/files/<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">bucket_id</span><span class="pl-kos">}</span></span>'</span>, <span class="pl-s1">stream</span><span class="pl-c1">=</span><span class="pl-c1">True</span>, <span class="pl-s1">headers</span><span class="pl-c1">=</span>{<span class="pl-s">'Accept'</span>: <span class="pl-s">'text/event-stream'</span>})
    <span class="pl-k">for</span> <span class="pl-s1">line</span> <span class="pl-c1">in</span> <span class="pl-s1">response</span>.<span class="pl-c1">iter_lines</span>():
      <span class="pl-k">if</span> <span class="pl-s1">line</span>:
          <span class="pl-s1">line</span> <span class="pl-c1">=</span> <span class="pl-s1">line</span>.<span class="pl-c1">decode</span>(<span class="pl-s">'utf-8'</span>)
          <span class="pl-k">if</span> <span class="pl-s1">line</span>.<span class="pl-c1">startswith</span>(<span class="pl-s">'data:'</span>):
              <span class="pl-k">try</span>:
                  <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-s1">json</span>.<span class="pl-c1">loads</span>(<span class="pl-s1">line</span>[<span class="pl-c1">5</span>:]) <span class="pl-c">#remove data: prefix</span>
                  <span class="pl-k">if</span> <span class="pl-s">"action"</span> <span class="pl-c1">in</span> <span class="pl-s1">data</span>:
                      <span class="pl-en">print</span>(<span class="pl-s">f"SSE Event: <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">data</span><span class="pl-kos">}</span></span>"</span>)
                  <span class="pl-k">elif</span> <span class="pl-s">"error"</span> <span class="pl-c1">in</span> <span class="pl-s1">data</span>:
                      <span class="pl-en">print</span>(<span class="pl-s">f"Error: <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">data</span>[<span class="pl-s">'error'</span>][<span class="pl-s">'message'</span>]<span class="pl-kos">}</span></span>"</span>)
                  <span class="pl-k">else</span>:
                      <span class="pl-en">print</span>(<span class="pl-s">f"File data received: <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">data</span><span class="pl-kos">}</span></span>"</span>) <span class="pl-c">#Assuming it's file content</span>
              <span class="pl-k">except</span> <span class="pl-s1">json</span>.<span class="pl-c1">JSONDecodeError</span> <span class="pl-k">as</span> <span class="pl-s1">e</span>:
                  <span class="pl-en">print</span>(<span class="pl-s">f"Error decoding JSON: <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">e</span><span class="pl-kos">}</span></span>"</span>)
          <span class="pl-k">else</span>:
              <span class="pl-en">print</span>(<span class="pl-s">f"Unhandled SSE event: <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">line</span><span class="pl-kos">}</span></span>"</span>)
    <span class="pl-s1">response</span>.<span class="pl-c1">close</span>()
    <span class="pl-k">return</span> <span class="pl-s1">bucket_id</span>

<span class="pl-c"># Example with URLs</span>
<span class="pl-s1">urls</span> <span class="pl-c1">=</span> [{<span class="pl-s">"url"</span>: <span class="pl-s">"https://github.com/xtekky/gpt4free/issues"</span>}]
<span class="pl-s1">bucket_id</span> <span class="pl-c1">=</span> <span class="pl-en">upload_and_process</span>(<span class="pl-s1">urls</span>)

<span class="pl-c">#Example with files</span>
<span class="pl-s1">files</span> <span class="pl-c1">=</span> {<span class="pl-s">'files'</span>: (<span class="pl-s">'document.pdf'</span>, <span class="pl-en">open</span>(<span class="pl-s">'document.pdf'</span>, <span class="pl-s">'rb'</span>))}
<span class="pl-s1">bucket_id</span> <span class="pl-c1">=</span> <span class="pl-en">upload_and_process</span>(<span class="pl-s1">files</span>)</pre></div>
<p><strong>Usage of Uploaded Files:</strong></p>
<div class="highlight highlight-source-python"><pre><span class="pl-k">from</span> <span class="pl-s1">g4f</span>.<span class="pl-s1">client</span> <span class="pl-k">import</span> <span class="pl-v">Client</span>

<span class="pl-c"># Enable debug mode</span>
<span class="pl-k">import</span> <span class="pl-s1">g4f</span>.<span class="pl-s1">debug</span>
<span class="pl-s1">g4f</span>.<span class="pl-c1">debug</span>.<span class="pl-c1">logging</span> <span class="pl-c1">=</span> <span class="pl-c1">True</span>

<span class="pl-s1">client</span> <span class="pl-c1">=</span> <span class="pl-en">Client</span>()

<span class="pl-c"># Upload example file</span>
<span class="pl-s1">files</span> <span class="pl-c1">=</span> {<span class="pl-s">'files'</span>: (<span class="pl-s">'demo.docx'</span>, <span class="pl-en">open</span>(<span class="pl-s">'demo.docx'</span>, <span class="pl-s">'rb'</span>))}
<span class="pl-s1">bucket_id</span> <span class="pl-c1">=</span> <span class="pl-en">upload_and_process</span>(<span class="pl-s1">files</span>)

<span class="pl-c"># Send request with file:</span>
<span class="pl-s1">response</span> <span class="pl-c1">=</span> <span class="pl-s1">client</span>.<span class="pl-c1">chat</span>.<span class="pl-c1">completions</span>.<span class="pl-c1">create</span>(
    [{<span class="pl-s">"role"</span>: <span class="pl-s">"user"</span>, <span class="pl-s">"content"</span>: [
        {<span class="pl-s">"type"</span>: <span class="pl-s">"text"</span>, <span class="pl-s">"text"</span>: <span class="pl-s">"Discribe this file."</span>},
        {<span class="pl-s">"bucket_id"</span>: <span class="pl-s1">bucket_id</span>}
    ]}],
)
<span class="pl-en">print</span>(<span class="pl-s1">response</span>.<span class="pl-c1">choices</span>[<span class="pl-c1">0</span>].<span class="pl-c1">message</span>.<span class="pl-c1">content</span>)</pre></div>
<p><strong>Example Output:</strong></p>
<pre><code>This document is a demonstration of the DOCX Input plugin capabilities in the software ...
</code></pre>
<p><strong>Example Usage (JavaScript):</strong></p>
<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">uuid</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">return</span> <span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-c1">1e7</span><span class="pl-kos">]</span><span class="pl-c1">+</span><span class="pl-c1">-</span><span class="pl-c1">1e3</span><span class="pl-c1">+</span><span class="pl-c1">-</span><span class="pl-c1">4e3</span><span class="pl-c1">+</span><span class="pl-c1">-</span><span class="pl-c1">8e3</span><span class="pl-c1">+</span><span class="pl-c1">-</span><span class="pl-c1">1e11</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">replace</span><span class="pl-kos">(</span><span class="pl-pds"><span class="pl-c1">/</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-c1">1</span><span class="pl-c1">8</span><span class="pl-kos">]</span><span class="pl-c1">/</span>g</span><span class="pl-kos">,</span> <span class="pl-s1">c</span> <span class="pl-c1">=&gt;</span>
      <span class="pl-kos">(</span><span class="pl-s1">c</span> <span class="pl-c1">^</span> <span class="pl-s1">crypto</span><span class="pl-kos">.</span><span class="pl-en">getRandomValues</span><span class="pl-kos">(</span><span class="pl-k">new</span> <span class="pl-v">Uint8Array</span><span class="pl-kos">(</span><span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span> <span class="pl-c1">&amp;</span> <span class="pl-c1">15</span> <span class="pl-c1">&gt;&gt;</span> <span class="pl-s1">c</span> <span class="pl-c1">/</span> <span class="pl-c1">4</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toString</span><span class="pl-kos">(</span><span class="pl-c1">16</span><span class="pl-kos">)</span>
    <span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">upload_files_or_urls</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">let</span> <span class="pl-s1">bucket_id</span> <span class="pl-c1">=</span> <span class="pl-en">uuid</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Use a random generated key for your bucket</span>

    <span class="pl-k">let</span> <span class="pl-s1">formData</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">FormData</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-k">typeof</span> <span class="pl-s1">data</span> <span class="pl-c1">===</span> <span class="pl-s">"object"</span> <span class="pl-c1">&amp;&amp;</span> <span class="pl-s1">data</span><span class="pl-kos">.</span><span class="pl-c1">constructor</span> <span class="pl-c1">===</span> <span class="pl-v">Array</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-c">//URLs</span>
        <span class="pl-k">const</span> <span class="pl-s1">blob</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">Blob</span><span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-c1">JSON</span><span class="pl-kos">.</span><span class="pl-en">stringify</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">)</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">type</span>: <span class="pl-s">'application/json'</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-k">const</span> <span class="pl-s1">file</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">File</span><span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-s1">blob</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-s">'downloads.json'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">type</span>: <span class="pl-s">'application/json'</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Create File object</span>
        <span class="pl-s1">formData</span><span class="pl-kos">.</span><span class="pl-en">append</span><span class="pl-kos">(</span><span class="pl-s">'files'</span><span class="pl-kos">,</span> <span class="pl-s1">file</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Append as a file</span>
    <span class="pl-kos">}</span> <span class="pl-k">else</span> <span class="pl-kos">{</span> <span class="pl-c">//Files</span>
        <span class="pl-v">Array</span><span class="pl-kos">.</span><span class="pl-en">from</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">forEach</span><span class="pl-kos">(</span><span class="pl-s1">file</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
            <span class="pl-s1">formData</span><span class="pl-kos">.</span><span class="pl-en">append</span><span class="pl-kos">(</span><span class="pl-s">'files'</span><span class="pl-kos">,</span> <span class="pl-s1">file</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>

    <span class="pl-k">await</span> <span class="pl-en">fetch</span><span class="pl-kos">(</span><span class="pl-s">"/v1/files/"</span> <span class="pl-c1">+</span> <span class="pl-s1">bucket_id</span><span class="pl-kos">,</span> <span class="pl-kos">{</span>
        <span class="pl-c1">method</span>: <span class="pl-s">'POST'</span><span class="pl-kos">,</span>
        <span class="pl-c1">body</span>: <span class="pl-s1">formData</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

    <span class="pl-k">function</span> <span class="pl-en">connectToSSE</span><span class="pl-kos">(</span><span class="pl-s1">url</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-k">const</span> <span class="pl-s1">eventSource</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">EventSource</span><span class="pl-kos">(</span><span class="pl-s1">url</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-s1">eventSource</span><span class="pl-kos">.</span><span class="pl-en">onmessage</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">event</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
            <span class="pl-k">const</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-c1">JSON</span><span class="pl-kos">.</span><span class="pl-en">parse</span><span class="pl-kos">(</span><span class="pl-s1">event</span><span class="pl-kos">.</span><span class="pl-c1">data</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
            <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">.</span><span class="pl-c1">error</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
                <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">error</span><span class="pl-kos">(</span><span class="pl-s">"Error:"</span><span class="pl-kos">,</span> <span class="pl-s1">data</span><span class="pl-kos">.</span><span class="pl-c1">error</span><span class="pl-kos">.</span><span class="pl-c1">message</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
            <span class="pl-kos">}</span> <span class="pl-k">else</span> <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">.</span><span class="pl-c1">action</span> <span class="pl-c1">===</span> <span class="pl-s">"done"</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
                <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">"Files loaded successfully. Bucket ID:"</span><span class="pl-kos">,</span> <span class="pl-s1">bucket_id</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
                <span class="pl-c">// Use bucket_id in your LLM prompt.</span>
                <span class="pl-k">const</span> <span class="pl-s1">prompt</span> <span class="pl-c1">=</span> <span class="pl-s">`Use files from bucket. <span class="pl-s1"><span class="pl-kos">${</span><span class="pl-c1">JSON</span><span class="pl-kos">.</span><span class="pl-en">stringify</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-s">"bucket_id"</span>: <span class="pl-s1">bucket_id</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">}</span></span> to answer this: ...your question...`</span><span class="pl-kos">;</span>
                <span class="pl-c">// ... Send prompt to your language model ...</span>
            <span class="pl-kos">}</span> <span class="pl-k">else</span> <span class="pl-kos">{</span>
                <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">"SSE Event:"</span><span class="pl-kos">,</span> <span class="pl-s1">data</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Update UI with progress as needed</span>
            <span class="pl-kos">}</span>
        <span class="pl-kos">}</span><span class="pl-kos">;</span>
        <span class="pl-s1">eventSource</span><span class="pl-kos">.</span><span class="pl-en">onerror</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">event</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
            <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">error</span><span class="pl-kos">(</span><span class="pl-s">"SSE Error:"</span><span class="pl-kos">,</span> <span class="pl-s1">event</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
            <span class="pl-s1">eventSource</span><span class="pl-kos">.</span><span class="pl-en">close</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-kos">}</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>

    <span class="pl-en">connectToSSE</span><span class="pl-kos">(</span><span class="pl-s">`/v1/files/<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">bucket_id</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">//Retrieve and refine</span>
<span class="pl-kos">}</span>

<span class="pl-c">// Example with URLs</span>
<span class="pl-k">const</span> <span class="pl-s1">urls</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">{</span><span class="pl-s">"url"</span>: <span class="pl-s">"https://github.com/xtekky/gpt4free/issues"</span><span class="pl-kos">}</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
<span class="pl-en">upload_files_or_urls</span><span class="pl-kos">(</span><span class="pl-s1">urls</span><span class="pl-kos">)</span>

<span class="pl-c">// Example with files (using a file input element)</span>
<span class="pl-k">const</span> <span class="pl-s1">fileInput</span> <span class="pl-c1">=</span> <span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">'fileInput'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-s1">fileInput</span><span class="pl-kos">.</span><span class="pl-en">addEventListener</span><span class="pl-kos">(</span><span class="pl-s">'change'</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-en">upload_files_or_urls</span><span class="pl-kos">(</span><span class="pl-s1">fileInput</span><span class="pl-kos">.</span><span class="pl-c1">files</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p><strong>Integrating with <code>ChatCompletion</code>:</strong></p>
<p>To incorporate file uploads into your client applications, include the <code>bucket</code> in your chat completion requests, using inline content parts.</p>
<div class="highlight highlight-source-json"><pre>{
  <span class="pl-ent">"messages"</span>: [
    {
      <span class="pl-ent">"role"</span>: <span class="pl-s"><span class="pl-pds">"</span>user<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"content"</span>: [
        {<span class="pl-ent">"type"</span>: <span class="pl-s"><span class="pl-pds">"</span>text<span class="pl-pds">"</span></span>, <span class="pl-ent">"text"</span>: <span class="pl-s"><span class="pl-pds">"</span>Answer this question using the files in the specified bucket: ...your question...<span class="pl-pds">"</span></span>},
        {<span class="pl-ent">"bucket_id"</span>: <span class="pl-s"><span class="pl-pds">"</span>your_actual_bucket_id<span class="pl-pds">"</span></span>}
      ]
    }
  ]
}</pre></div>
<p><strong>Important Considerations:</strong></p>
<ul>
<li>
<strong>Error Handling:</strong> Implement robust error handling in both Python and JavaScript to gracefully manage potential issues during file uploads, downloads, and API interactions.</li>
<li>
<strong>Dependencies:</strong> Ensure all required packages are installed (<code>pip install -U g4f[files]</code> for Python).</li>
</ul>
<hr>
<div class="markdown-heading"><h2 class="heading-element">📄 MarkItDown – Lightweight File-to-Text API (Alternative to G4F File API)</h2><a id="user-content--markitdown--lightweight-file-to-text-api-alternative-to-g4f-file-api" class="anchor" aria-label="Permalink: 📄 MarkItDown – Lightweight File-to-Text API (Alternative to G4F File API)" href="#-markitdown--lightweight-file-to-text-api-alternative-to-g4f-file-api"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
<p><code>markitdown</code> is a simple and lightweight alternative to the G4F File API for extracting <strong>plain or markdown-formatted text</strong> from uploaded files. While the G4F File API supports bucket-based multi-file workflows and streaming, <code>markitdown</code> is ideal for <strong>quick, direct conversion of individual files</strong> (e.g. <code>.pdf</code>, <code>.docx</code>, <code>.wav</code>, etc.).</p>
<div class="markdown-heading"><h3 class="heading-element">✅ Key Features</h3><a id="user-content--key-features" class="anchor" aria-label="Permalink: ✅ Key Features" href="#-key-features"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
<ul>
<li>🔄 Converts a wide range of files (PDF, DOCX, TXT, AUDIO, etc.) to markdown/plain text.</li>
<li>📤 Simple POST API: Send a file, receive extracted text.</li>
<li>⚡ Fast, no bucket, SSE, or URL fetch needed.</li>
<li>🎯 Ideal for use-cases where full document text is needed inline in chat prompts.</li>
</ul>
<hr>
<div class="markdown-heading"><h3 class="heading-element">📦 Installation</h3><a id="user-content--installation" class="anchor" aria-label="Permalink: 📦 Installation" href="#-installation"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
<div class="highlight highlight-source-shell"><pre>pip install markitdown[all]</pre></div>
<hr>
<div class="markdown-heading"><h3 class="heading-element">🐍 Example Usage (Python)</h3><a id="user-content--example-usage-python" class="anchor" aria-label="Permalink: 🐍 Example Usage (Python)" href="#-example-usage-python"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
<div class="highlight highlight-source-python"><pre><span class="pl-k">import</span> <span class="pl-s1">requests</span>

<span class="pl-k">def</span> <span class="pl-en">convert_with_markitdown</span>(<span class="pl-s1">file_path</span>):
    <span class="pl-k">with</span> <span class="pl-en">open</span>(<span class="pl-s1">file_path</span>, <span class="pl-s">'rb'</span>) <span class="pl-k">as</span> <span class="pl-s1">file</span>:
        <span class="pl-s1">response</span> <span class="pl-c1">=</span> <span class="pl-s1">requests</span>.<span class="pl-c1">post</span>(<span class="pl-s">'http://localhost:8080/api/markitdown'</span>, <span class="pl-s1">files</span><span class="pl-c1">=</span>{<span class="pl-s">'file'</span>: <span class="pl-s1">file</span>})
        <span class="pl-k">if</span> <span class="pl-s1">response</span>.<span class="pl-c1">status_code</span> <span class="pl-c1">==</span> <span class="pl-c1">200</span>:
            <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-s1">response</span>.<span class="pl-c1">json</span>()
            <span class="pl-k">return</span> <span class="pl-s1">data</span>[<span class="pl-s">'text'</span>]
        <span class="pl-k">else</span>:
            <span class="pl-k">raise</span> <span class="pl-en">Exception</span>(<span class="pl-s">f"Conversion failed: <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">response</span>.<span class="pl-c1">status_code</span><span class="pl-kos">}</span></span> - <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">response</span>.<span class="pl-c1">text</span><span class="pl-kos">}</span></span>"</span>)

<span class="pl-c"># Usage</span>
<span class="pl-s1">text</span> <span class="pl-c1">=</span> <span class="pl-en">convert_with_markitdown</span>(<span class="pl-s">'example.pdf'</span>)
<span class="pl-en">print</span>(<span class="pl-s1">text</span>)</pre></div>
<hr>
<div class="markdown-heading"><h3 class="heading-element">🌐 Example Usage (JavaScript)</h3><a id="user-content--example-usage-javascript" class="anchor" aria-label="Permalink: 🌐 Example Usage (JavaScript)" href="#-example-usage-javascript"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
<div class="highlight highlight-text-html-basic"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">input</span> <span class="pl-c1">type</span>="<span class="pl-s">file</span>" <span class="pl-c1">id</span>="<span class="pl-s">fileInput</span>" <span class="pl-kos">/&gt;</span>

<span class="pl-kos">&lt;</span><span class="pl-ent">script</span><span class="pl-kos">&gt;</span>
<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">convertToMarkdown</span><span class="pl-kos">(</span><span class="pl-s1">file</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">const</span> <span class="pl-s1">formData</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">FormData</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-s1">formData</span><span class="pl-kos">.</span><span class="pl-en">append</span><span class="pl-kos">(</span><span class="pl-s">'file'</span><span class="pl-kos">,</span> <span class="pl-s1">file</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

    <span class="pl-k">try</span> <span class="pl-kos">{</span>
        <span class="pl-k">const</span> <span class="pl-s1">response</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-en">fetch</span><span class="pl-kos">(</span><span class="pl-s">'http://localhost:8080/api/markitdown'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span>
            <span class="pl-c1">method</span>: <span class="pl-s">'POST'</span><span class="pl-kos">,</span>
            <span class="pl-c1">body</span>: <span class="pl-s1">formData</span>
        <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

        <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">response</span><span class="pl-kos">.</span><span class="pl-c1">ok</span><span class="pl-kos">)</span> <span class="pl-k">throw</span> <span class="pl-k">new</span> <span class="pl-v">Error</span><span class="pl-kos">(</span><span class="pl-s">`HTTP <span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">response</span><span class="pl-kos">.</span><span class="pl-c1">status</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

        <span class="pl-k">const</span> <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">response</span><span class="pl-kos">.</span><span class="pl-en">json</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">"Converted Text:"</span><span class="pl-kos">,</span> <span class="pl-s1">data</span><span class="pl-kos">.</span><span class="pl-c1">text</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

        <span class="pl-c">// You can now inject data.text into a prompt or display in the UI.</span>
    <span class="pl-kos">}</span> <span class="pl-k">catch</span> <span class="pl-kos">(</span><span class="pl-s1">error</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">error</span><span class="pl-kos">(</span><span class="pl-s">'Conversion failed:'</span><span class="pl-kos">,</span> <span class="pl-s1">error</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">'fileInput'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">addEventListener</span><span class="pl-kos">(</span><span class="pl-s">'change'</span><span class="pl-kos">,</span> <span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-k">const</span> <span class="pl-s1">file</span> <span class="pl-c1">=</span> <span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-c1">target</span><span class="pl-kos">.</span><span class="pl-c1">files</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
    <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">file</span><span class="pl-kos">)</span> <span class="pl-k">await</span> <span class="pl-en">convertToMarkdown</span><span class="pl-kos">(</span><span class="pl-s1">file</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">&lt;/</span><span class="pl-ent">script</span><span class="pl-kos">&gt;</span></pre></div>
<hr>
<div class="markdown-heading"><h3 class="heading-element">💬 Integration with ChatCompletion</h3><a id="user-content--integration-with-chatcompletion" class="anchor" aria-label="Permalink: 💬 Integration with ChatCompletion" href="#-integration-with-chatcompletion"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
<p>Once you retrieve <code>text</code> from <code>markitdown</code>, you can insert it into your LLM prompt as inline content:</p>
<div class="highlight highlight-source-json"><pre>{
  <span class="pl-ent">"messages"</span>: [
    {
      <span class="pl-ent">"role"</span>: <span class="pl-s"><span class="pl-pds">"</span>user<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"content"</span>: [
        { <span class="pl-ent">"type"</span>: <span class="pl-s"><span class="pl-pds">"</span>text<span class="pl-pds">"</span></span>, <span class="pl-ent">"text"</span>: <span class="pl-s"><span class="pl-pds">"</span>&lt;text_from_markitdown&gt;<span class="pl-pds">"</span></span> },
        { <span class="pl-ent">"type"</span>: <span class="pl-s"><span class="pl-pds">"</span>text<span class="pl-pds">"</span></span>, <span class="pl-ent">"text"</span>: <span class="pl-s"><span class="pl-pds">"</span>Answer this question using the above content: ...your question...<span class="pl-pds">"</span></span> }
      ]
    }
  ]
}</pre></div>
<p>Example in Python:</p>
<div class="highlight highlight-source-python"><pre><span class="pl-s1">response</span> <span class="pl-c1">=</span> <span class="pl-s1">client</span>.<span class="pl-c1">chat</span>.<span class="pl-c1">completions</span>.<span class="pl-c1">create</span>(
    <span class="pl-s1">messages</span><span class="pl-c1">=</span>[
        {
            <span class="pl-s">"role"</span>: <span class="pl-s">"user"</span>,
            <span class="pl-s">"content"</span>: [
                {<span class="pl-s">"type"</span>: <span class="pl-s">"text"</span>, <span class="pl-s">"text"</span>: <span class="pl-s1">text</span>},
                {<span class="pl-s">"type"</span>: <span class="pl-s">"text"</span>, <span class="pl-s">"text"</span>: <span class="pl-s">"Summarize this document."</span>}
            ]
        }
    ]
)</pre></div>
<hr>
<div class="markdown-heading"><h3 class="heading-element">🔄 G4F File API vs MarkItDown</h3><a id="user-content--g4f-file-api-vs-markitdown" class="anchor" aria-label="Permalink: 🔄 G4F File API vs MarkItDown" href="#-g4f-file-api-vs-markitdown"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
<table>
<thead>
<tr>
<th>Feature</th>
<th>G4F File API</th>
<th>MarkItDown API</th>
</tr>
</thead>
<tbody>
<tr>
<td>Upload Files</td>
<td>✅ Yes</td>
<td>✅ Yes</td>
</tr>
<tr>
<td>Web URL Downloads</td>
<td>✅ Yes via <code>downloads.json</code>
</td>
<td>❌ No</td>
</tr>
<tr>
<td>SSE Progress Streaming</td>
<td>✅ Yes</td>
<td>❌ No</td>
</tr>
<tr>
<td>Markdown/Text Output</td>
<td>Raw/structured</td>
<td>Clean markdown/plain text</td>
</tr>
<tr>
<td>Bucket/File Management</td>
<td>✅ Multi-file</td>
<td>❌ Single-file only</td>
</tr>
<tr>
<td>Use Case</td>
<td>Multi-step pipelines, large workflows</td>
<td>Quick extraction, inline usage</td>
</tr>
</tbody>
</table>
<hr>
<div class="markdown-heading"><h3 class="heading-element">📌 Summary</h3><a id="user-content--summary" class="anchor" aria-label="Permalink: 📌 Summary" href="#-summary"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
<ul>
<li>
<p>Use <strong>G4F File API</strong> when:</p>
<ul>
<li>You need to upload/download many files.</li>
<li>You want streamed SSE progress.</li>
<li>You're building a multi-step or large workflow.</li>
</ul>
</li>
<li>
<p>Use <strong>MarkItDown</strong> when:</p>
<ul>
<li>You want quick markdown/plain text extraction from a single file.</li>
<li>You plan to inject the text directly into an LLM prompt.</li>
<li>You prefer a simple one-call API.</li>
</ul>
</li>
</ul>
<hr>
<p><a href="/docs/">Return to Documentation</a></p>
</article>
</body>
</html>